package oss

import (
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"gopkg.in/yaml.v2"
)

var client *oss.Client
var bucketName = "xcblog"

// OSSConfig 配置结构体
type OSSConfig struct {
	OSS struct {
		AccessKeyID     string `yaml:"access_key_id"`
		AccessKeySecret string `yaml:"access_key_secret"`
		Endpoint        string `yaml:"endpoint"`
		BucketName      string `yaml:"bucket_name"`
		Region          string `yaml:"region"`
	} `yaml:"oss"`
}

func handleError(err error) {
	log.Fatalf("Error: %v", err)
}

// loadConfig 从配置文件加载配置
func loadConfig() (*OSSConfig, error) {
	config := &OSSConfig{}

	// 获取当前工作目录
	workDir, err := os.Getwd()
	if err != nil {
		log.Println("获取工作目录失败:", err)
		return nil, err
	}

	// 构建配置文件的绝对路径
	configPath := filepath.Join(workDir, "oss_config.yaml")
	if data, err := ioutil.ReadFile(configPath); err == nil {
		if err := yaml.Unmarshal(data, config); err != nil {
			log.Println("读取配置文件失败", err)
			return nil, err
		}
		return config, nil
	}
	log.Println("配置文件不存在:", configPath)
	log.Println("oss_config.yaml文件读取成功:", configPath)

	// 如果配置文件不存在，返回nil
	return nil, nil
}

func init() {
	var endpoint = "https://oss-cn-shanghai.aliyuncs.com"
	var region = "cn-shanghai"
	var accessKeyID, accessKeySecret string
	var err error

	// 首先尝试从配置文件读取
	if config, configErr := loadConfig(); configErr == nil && config != nil {
		endpoint = config.OSS.Endpoint
		bucketName = config.OSS.BucketName
		region = config.OSS.Region
		accessKeyID = config.OSS.AccessKeyID
		accessKeySecret = config.OSS.AccessKeySecret
		log.Println("使用配置文件中的OSS凭证")
	} else {
		// 如果配置文件不存在或读取失败，尝试从环境变量读取
		accessKeyID = os.Getenv("OSS_ACCESS_KEY_ID")
		accessKeySecret = os.Getenv("OSS_ACCESS_KEY_SECRET")
		if accessKeyID == "" || accessKeySecret == "" {
			log.Fatal("请设置OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET环境变量，或创建config.yaml配置文件")
		}
		log.Println("使用环境变量中的OSS凭证")
	}

	if endpoint == "" || bucketName == "" {
		log.Fatal("请设置endpoint和bucketName")
	}

	// 如果从配置文件或环境变量获取到了凭证，直接使用
	if accessKeyID != "" && accessKeySecret != "" {
		clientOptions := []oss.ClientOption{
			oss.Region(region),
			oss.AuthVersion(oss.AuthV4),
		}
		client, err = oss.New(endpoint, accessKeyID, accessKeySecret, clientOptions...)
	} else {
		// 否则使用环境变量凭证提供者
		provider, providerErr := oss.NewEnvironmentVariableCredentialsProvider()
		if providerErr != nil {
			handleError(providerErr)
		}
		clientOptions := []oss.ClientOption{
			oss.SetCredentialsProvider(&provider),
			oss.Region(region),
			oss.AuthVersion(oss.AuthV4),
		}
		client, err = oss.New(endpoint, "", "", clientOptions...)
	}

	if err != nil {
		handleError(err)
	}

	// 输出客户端信息
	log.Printf("OSS客户端初始化成功，Endpoint: %s, Bucket: %s\n", endpoint, bucketName)
}

func DownloadFile(objectName, downloadedFileName string) error {
	// 获取存储空间。
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		return err
	}

	// 下载文件。
	err = bucket.GetObjectToFile(objectName, downloadedFileName)
	if err != nil {
		return err
	}

	// 文件下载成功后，记录日志。
	log.Printf("File downloaded successfully to %s", downloadedFileName)
	return nil
}

func UploadFile(objectName string, localFileName io.Reader) (string, error) {
	// 获取存储空间。
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		return "", err
	}
	err = bucket.PutObject(objectName, localFileName)
	if err != nil {
		return "", err
	}
	// 上传文件。

	// 文件上传成功后，记录日志。
	log.Printf("File uploaded successfully to %s/%s", bucketName, objectName)
	path := "https://" + bucketName + "." + "oss-cn-shanghai.aliyuncs.com" + "/" + objectName
	return path, nil
}
